<?php
defined( 'BASEPATH' ) or exit( 'No direct script access allowed' );
class MY_Controller extends CI_Controller
{
    function __construct()
    {
        parent::__construct();
        
        // 开启缓存区
        for($level = ob_get_level(); $level > 0; -- $level)
        {
            ob_end_clean();
        }
        ob_start();
        
        // 加载公共配置
        if (! is_file( $file = FCPATH . 'conf/common.php' ))
        {
            show_error( 'The configuration file data/config.php does not exist.' );
        }
        include ($file);
        
        // 存储文件上传路径到控制器属性，以便子类可以访问
        if (isset( $upload_folder ))
        {
            $this->upload_folder = $upload_folder;
        }
        
        // 加载自定义的数据库访问
        if (! is_file( $file = APPPATH . 'include/MyPDO.class.php' ))
        {
            show_error( 'The class file MyPDO.class.php does not exist.' );
        }
        include ($file);
        $this->pdo = MyPDO::get_instance();
        // 数据库配置
        if (! isset( $active_group ))
        {
            show_error( 'You have not specified a database connection group via $active_group in your config/database.php file.' );
        }
        elseif (! isset( $db[$active_group] ))
        {
            show_error( 'You have specified an invalid database connection group (' . $active_group . ') in your config/database.php file.' );
        }
        if (! $this->pdo->connect( $db[$active_group] ))
        {
            exit();
        }
        
        // 标识客户端
        if (PHP_SAPI != 'cli' && ! isset( $_COOKIE['CLIENT_ID'] ))
        {
            $client_id = md5( $_SERVER['REQUEST_TIME_FLOAT'] );
            $_COOKIE['CLIENT_ID'] = $client_id;
            setcookie( 'CLIENT_ID', $client_id, 2147483647, '/' );
        }
        
        // 加载日志
        if (! is_file( $file = APPPATH . 'include/MyLog.class.php' ))
        {
            show_error( 'The class file MyLog.class.php does not exist.' );
        }
        include ($file);
        $this->mylog = MyLog::get_instance( array (
                'table_name_id' => 'admin_log_id',
                'table_name_request' => 'admin_log_request',
                'table_name_msg' => 'admin_log_msg',
                'flag' => 255 
        ) );
        
        // 加载自定义会话
        if (! is_file( $file = APPPATH . 'include/MySession.class.php' ))
        {
            show_error( 'The class file MySession.class.php does not exist.' );
        }
        include ($file);
        MySession::get_instance( array (
                'session_name' => 'USER' 
        ) );
        
        // 加载用户辅助
        if (! is_file( $file = APPPATH . 'include/UserHelper.class.php' ))
        {
            show_error( 'The class file UserHelper.class.php does not exist.' );
        }
        include ($file);
        
        // 是否ajax请求（所有处理ajax请求的接口均位于ajax目录下）
        $is_ajax = strtolower( $this->router->directory ) == 'ajax/' ? true : false;
        
        // 根据不同请求，加载不同类
        if ($is_ajax)
        {
            // 加载ajax返回器
            $this->load->library( 'JsonResult', array (
                    'callback' => $this->input->get( 'callback' ),
                    'debug' => true 
            ), 'rs' );
        }
        else
        {
            //
        }
        
        // 判断登陆
        $request = $this->router->directory . $this->router->class . '/' . $this->router->method;
        $request = ltrim( strtolower( $request ), '/' );
        $this->request = $request;
        // echo $request;
        if (! in_array( $request, $this->config->item( 'login_exclude' ) ))
        {
            // 请求需要验证登录
            if (! UserHelper::check_login( true ))
            {
                // 未登录
                if ($is_ajax)
                {
                    $this->rs->err( 3 );
                }
                else
                {
                    header( "location:" . site_url( "ui/login" ) );
                }
                exit();
            }
            $this->user = $_SESSION['user'];
            $this->load->vars( 'user', $_SESSION['user'] );
            
            // 根据“控制器/方法”判断用户权限（已登录）
            if (! in_array( $request, $this->config->item( 'permission_exclude' ) ))
            {
                if (! $this->check_permission())
                {
                    if ($is_ajax)
                    {
                        $this->rs->err( 4 );
                    }
                    else
                    {
                        $_SESSION['err_msg'] = "页面“{$request}”无访问权限！";
                        header( "location:" . site_url( "ui/index" ) );
                    }
                    exit();
                }
            }
            
            // 加载菜单（已登录且有访问权限）
            if (! $is_ajax)
            {
                $this->load_menu();
            }
            
            $this->load->vars( 'upload_folder', $this->upload_folder );
        }
    }
    function test()
    {
        echo 'This is a test function in controller.';
    }
    protected function check_permission($uri = null)
    {
        $this->load->model( 'user_permission_model' );
        return $this->user_permission_model->check( $this->user['role_id'], empty( $uri ) ? $this->request : $uri );
    }
    protected function check_csrf($token)
    {
        return (! empty( $this->user['CSRF'] ) && $this->user['CSRF'] == $token);
    }
    private function load_menu()
    {
        // 加载当前位置辅助类
        $this->load->library( 'Location' );
        // 用户菜单
        $this->load->model( 'user_permission_model' );
        $uris = array ();
        foreach ( $this->user_permission_model->uris( $this->user['role_id'], 1 ) as $i )
        {
            $uris[] = $i['uri'];
        }
        $this->load->model( 'menu_model' );
        $menus = $this->menu_model->get( $uris );
        if (empty( $menus ))
        {
            return;
        }
        $menu_data = array ();
        $fid = 0;
        foreach ( $menus as $m )
        {
            // 定位二级菜单信息
            if ($m['uri'] == $this->request)
            {
                $this->location->add( $m['name'], '', '', '', 2 );
                $fid = $m['fid'];
                $m['active'] = true;
            }
            // 分组菜单数据
            $menu_data[$m['fid']][] = $m;
        }
        // 定位一级菜单信息
        foreach ( $menu_data[0] as &$root_menu )
        {
            if ($root_menu['id'] == $fid)
            {
                $this->location->add( $root_menu['name'], '', '', '', 1 );
                $root_menu['current'] = true;
            }
        }
        // “分配”数据到视图
        $this->load->vars( 'menu', $menu_data );
        $this->load->vars( 'location', $this->location->get_data() );
    }
}